package com.example.algorithm.huawei_rongyao_29;

// 二进制插入
// 难度：完全看不懂哦。也不知道为什么要做这个操作。

import java.util.Scanner;

/**
 * 给定两个32位整数n和m，同时给定i和j，将m的二进制数位插入到n的二进制的第j到第i位,保证n的第j到第i位均为零，且m的二进制位数小于等于i-j+1，其中二进制的位数从0开始由低到高。
 * 测试样例：
 * 1024,19,2,6      // 10000000000 is 1024 in binary    // 10011 is 19 in binary
 * 返回：1100
 *
 * 虽然没有看懂。但是实际测试以下程序正常工作。
 */
public class Q27_BinaryInsertion {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        int[] nambers = Utils.scannerAndSplitWithCommaAndTransIntoInt(line);
        int N = nambers[0];
        int M = nambers[1];
        int i = nambers[2];
        int j = nambers[3];

        int result = insertBits(N, M, i, j);

        System.out.println("结果: " + result); // 这个是十进制结果
        System.out.println("二进制结果: " + Integer.toBinaryString(result)); // 这个是二进制结果可以不打印
    }

    public static int insertBits(int N, int M, int i, int j) {
        // Step 1: Create a mask to clear bits i through j in N
        int allOnes = ~0; // allOnes will be equal to 11111111...111 in binary

        // 1s before position j, then 0s
        int left = allOnes << (j + 1); // 1 << (j+1) will be 100000...00000 (j+1 zeros)

        // 1s after position i
        int right = ((1 << i) - 1); // 1 << i will be 10000...000 (i zeros), subtract 1 to get 01111...111 (i ones)

        // All 1s, except for 0s between i and j
        int mask = left | right;

        // Step 2: Clear bits j through i then put M in there
        int n_cleared = N & mask; // Clear bits j through i.
        int m_shifted = M << i;   // Move M into the correct position.

        // OR them, and we're done!
        return n_cleared | m_shifted;
    }
}

